﻿/**************************************************************************************
 * SPFileHelper.cs
 * An extension class for the SPFile Sharepoint Foundation Object.
 * Jaime Alberto Jaramillo Zapata (jjaramillo.informatica-tecnologia.com)
 * Created on 06/02/2012.
 * Last update on 06/02/2012.
 **************************************************************************************/

using System;
using Microsoft.SharePoint;
using MS.InformationManagement.Support.Constants;

namespace MS.InformationManagement.Support
{
    /// <summary>
    /// An extension class for the SPFile Sharepoint Foundation Object.
    /// </summary>
    public static class SPFileHelper
    {
        /// <summary>
        /// Moves to SPFile and its previous versions to another document library on the same Sharepoint Foundation site.
        /// </summary>
        /// <param name="spFile">The SPFile to be moved.</param>
        /// <param name="libraryPath">The document library in which the SPFile is going to be stored's path .</param>
        /// <param name="folderStructure">The folder structure inside the library in which the SPFile is going to be stored.</param>
        /// <param name="overwrite">if set to <c>true</c> [overwrite].</param>
        /// <returns>The SPFile's new server relative url</returns>
        public static string MoveTo(this SPFile spFile, string libraryPath, string folderStructure, bool overwrite)
        {
            string newLocationUrl = string.Empty;
            SPWeb currentWeb = spFile.Web;
            SPDocumentLibrary targetLibrary = currentWeb.GetList(string.Format("{0}/{1}", currentWeb.Url, libraryPath)) as SPDocumentLibrary;

            if (targetLibrary != null)
            {
                SPFolder currentSPFolder = targetLibrary.RootFolder;

                /*
                 * If there is a folder structure check if it exists, and if not create it recursively
                 */

                if (!string.IsNullOrEmpty(folderStructure))
                {
                    string[] folders = folderStructure.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                    string fullCurrentFolderPath = string.Format("{0}/{1}", currentWeb.Url, libraryPath);
                    string currentFolderPath = string.Empty;

                    foreach (string currentFolder in folders)
                    {
                        fullCurrentFolderPath = string.Format("{0}/{1}", fullCurrentFolderPath, currentFolder);
                        currentFolderPath = string.Format("{0}/{1}", currentFolderPath, currentFolder);
                        SPFolder targetFolder = currentWeb.GetFolder(fullCurrentFolderPath);

                        if (!targetFolder.Exists)
                        {
                            currentSPFolder = currentSPFolder.SubFolders.Add(currentFolder);
                        }
                        else
                        {
                            currentSPFolder = targetFolder;
                        }
                    }
                }
                /*
                 * If there's no folder structure, just grab the target library's root folder
                 */
                else
                {
                    currentSPFolder = targetLibrary.RootFolder;
                }

                /*
                 * Move the SPFileVersions, one at a time, to the target library, copying the versioning metadata that does not move on with the
                 * SPFile.MoveTo function
                 */

                SPFileVersionCollection spFileVersions = spFile.Versions;
                currentWeb.AllowUnsafeUpdates = true;

                if (spFileVersions.Count > 0)
                {
                    foreach (SPFileVersion currentVersion in spFile.Versions)
                    {
                        SPFile spFileVersion = currentSPFolder.Files.Add(spFile.Name, currentVersion.OpenBinary(), currentVersion.Properties, overwrite);

                        spFileVersion.Properties[SPVersioningColumnNames.SOURCECONTROLCHECKINCOMMENT] = currentVersion.Properties[SPVersioningColumnNames.SOURCECONTROLCHECKINCOMMENT] ?? string.Empty;
                        spFileVersion.Properties[SPVersioningColumnNames.AUTHOR] = currentVersion.Properties[SPVersioningColumnNames.AUTHOR];
                        spFileVersion.Properties[SPVersioningColumnNames.MODIFIEDBY] = currentVersion.Properties[SPVersioningColumnNames.MODIFIEDBY];
                        spFileVersion.Properties[SPVersioningColumnNames.TIMELASTMODIFIED] = currentVersion.Properties[SPVersioningColumnNames.TIMELASTMODIFIED];
                        
                        spFileVersion.Update();
                    }
                }

                /*
                 * Move the latest SPFile version
                 */

                SPFile latestVersion = currentSPFolder.Files.Add(spFile.Name, spFile.OpenBinary(), spFile.Properties, overwrite);
                latestVersion.Properties[SPVersioningColumnNames.SOURCECONTROLCHECKINCOMMENT] = spFile.Properties[SPVersioningColumnNames.SOURCECONTROLCHECKINCOMMENT] ?? string.Empty;
                latestVersion.Properties[SPVersioningColumnNames.AUTHOR] = spFile.Properties[SPVersioningColumnNames.AUTHOR];
                latestVersion.Properties[SPVersioningColumnNames.MODIFIEDBY] = spFile.Properties[SPVersioningColumnNames.MODIFIEDBY];
                latestVersion.Properties[SPVersioningColumnNames.TIMELASTMODIFIED] = spFile.Properties[SPVersioningColumnNames.TIMELASTMODIFIED];

                latestVersion.Update();

                currentWeb.AllowUnsafeUpdates = false;

                newLocationUrl = latestVersion.ServerRelativeUrl;

                /*
                 * Finally, delete the SPFile from its original location
                 */

                spFile.Delete();
            }

            return newLocationUrl;
        }
    }
}
